package com.xo.file.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.PutObjectRequest;
import com.xo.common.Result.ResultResponse;
import com.xo.common.constant.CommonConstant;
import com.xo.common.constant.CommonSymbolConstant;
import com.xo.common.enums.ResultEnum;
import com.xo.common.until.ExceptionUtil;
import com.xo.file.config.ConfigurationProperties.CosConfigurationProperties;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.UUID;

@RestController
@Tag(name = "腾讯Cos上传文件")
@RequestMapping("/file/cos")
@Slf4j
public class CosController {

    @Resource
    private CosConfigurationProperties cosConfigurationProperties;

    @Resource
    private COSClient cosClient;

    @Value("${file.max-size}") // 10MB默认
    private Long maxFileSize;


    @PostMapping("/upload/file")
    @Operation(summary = "上传文件到腾讯云cos", description = "上传文件到腾讯云cos")
    @ApiOperationSupport(author = "dayu", order = 1)
    public ResultResponse<Object> uploadFile(MultipartFile multipartFile, String path) {

        //参数校验
        ResultResponse<Object> resultResponse = validateFile(multipartFile, path);
        if (resultResponse.getStatus().equals(Boolean.FALSE)) {
            return resultResponse;
        }
        //上传文件到cos并拿到文件路径
        String cosUrl = uploadFileToCos(multipartFile, path);

        if (StringUtils.isBlank(cosUrl)) {
            return ResultResponse.fail(ResultEnum.FILE_UPLOAD_FAIL);
        }

        return ResultResponse.success(cosUrl);
    }


    @Operation(summary = "上传文件到cos", description = "上传文件到cos")
    private String uploadFileToCos(MultipartFile multipartFile, String path) {
        String originalFilename = multipartFile.getOriginalFilename();
        UUID uuid = UUID.randomUUID();
        String key = path + CommonSymbolConstant.FORWARD_SLASH + uuid + originalFilename;

        File tempFile = null;

        try {

            tempFile = File.createTempFile(CommonConstant.temp, originalFilename);
            multipartFile.transferTo(tempFile);
            PutObjectRequest putObjectRequest = new PutObjectRequest(cosConfigurationProperties.getBucketName(), key, tempFile);
            cosClient.putObject(putObjectRequest);

            String fileName = uuid + originalFilename;
            return cosConfigurationProperties.getCosUrl(fileName);
        } catch (IOException e) {
            // 处理文件IO异常
            log.error(CommonSymbolConstant.appendLog(ResultEnum.FILE_HANDLE_ERROR.getMessage()), originalFilename, e);
            ExceptionUtil.throwException(CommonSymbolConstant.appendLog(ResultEnum.FILE_HANDLE_ERROR.getMessage()));
        } catch (Exception e) {
            // 处理其他异常
            log.error(CommonSymbolConstant.appendLog(ResultEnum.FILE_UPLOAD_ERROR.getMessage()), originalFilename, e);
            ExceptionUtil.throwException(ResultEnum.FILE_UPLOAD_FAIL.getMessage());
        } finally {
            // 删除临时文件
            cleanupTempFile(tempFile);
        }
        return null;
    }

    @Operation(summary = "验证文件", description = "验证文件是否符合上传要求")
    private ResultResponse<Object> validateFile(MultipartFile file, String path) {
        if (file == null || file.isEmpty()) {
            return ResultResponse.fail(ResultEnum.FILE_NAME_NOT_EMPTY);
        }

        String filename = file.getOriginalFilename();
        if (StringUtils.isBlank(filename)) {
            return ResultResponse.fail(ResultEnum.FILE_NAME_NOT_EMPTY);
        }

        if (StringUtils.isBlank(path)) {
            return ResultResponse.fail(ResultEnum.FILE_UPLOAD_PATH_NOT_EMPTY);
        }

        // 文件大小预检查
        if (file.getSize() > maxFileSize) {
            return ResultResponse.fail(ResultEnum.FILE_SIZE_OVER_LIMIT);
        }

        return ResultResponse.success();
    }

    @Operation(summary = "清理临时文件", description = "清理临时文件")
    @ApiOperationSupport(author = "dayu")
    private void cleanupTempFile(File tempFile) {
        if (tempFile != null) {
            try {
                Files.deleteIfExists(tempFile.toPath());
            } catch (IOException e) {
                log.warn(ResultEnum.DELETE_TEMP_FILE_FAIL + CommonSymbolConstant.CURLY_BRACKETS, tempFile.getAbsolutePath());
                tempFile.deleteOnExit();
            }
        }
    }

}


